package com.xcexample.electronicclasscard;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Json转换工具类
 */
public class JsonHelper {
	
	private JsonHelper() {
		throw new UnsupportedOperationException("u can't instantiate me...");
	}
	
	private static Gson mGson = new Gson();
	
	/**
	 * 将对象准换为json字符串
	 */
	public static <T> String serialize(T object) {
		return mGson.toJson(object);
	}
	
	/**
	 * 将json字符串转换为对象
	 */
	public static <T> T deserialize(String json, Class<T> clz) throws JsonSyntaxException {
		return mGson.fromJson(json, clz);
	}
	
	/**
	 * 将json对象转换为实体对象
	 */
	public static <T> T deserialize(JsonObject json, Class<T> clz) throws JsonSyntaxException {
		return mGson.fromJson(json, clz);
	}
	
	/**
	 * 将json字符串转换为对象
	 */
	public static <T> T deserialize(String json, Type type) throws JsonSyntaxException {
		return mGson.fromJson(json, type);
	}
	
	/**
	 * 转成list
	 * 泛型在编译期类型被擦除导致报错
	 */
	public static <T> List<T> gsonToList(String gsonString, Class<T> cls) {
		return mGson.fromJson(gsonString, new TypeToken<List<T>>() {
		}.getType());
	}
	
	public static String beanToJson(Object object) {
		return mGson.toJson(object);
	}
	/**
	 * Convert a json string to List<?>
	 */
	public static <T> List<T> jsonToList(String json) {
		return mGson.fromJson(json, new TypeToken<List<T>>() {
		}.getType());
	}
	
	/**
	 * 转成list
	 * 解决泛型问题
	 */
	public static <T> List<T> jsonToList(String json, Class<T> cls) {
		List<T> list = new ArrayList<T>();
		JsonArray array = new JsonParser().parse(json).getAsJsonArray();
		for (final JsonElement elem : array) {
			list.add(mGson.fromJson(elem, cls));
		}
		return list;
	}
	
	/**
	 * 转成list中有map的
	 */
	public static <T> List<Map<String, T>> gsonToListMaps(String gsonString) {
		return mGson.fromJson(gsonString, new TypeToken<List<Map<String, T>>>() {
		}.getType());
	}
	
	/**
	 * 转成map的
	 */
	public static <T> Map<String, T> gsonToMaps(String gsonString) {
		return mGson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
		}.getType());
	}
	
	/**
	 * Convert a json string to ArrayList<?>
	 */
	public static <T> ArrayList<T> jsonToArrayList(String json) {
		return mGson.fromJson(json, new TypeToken<ArrayList<T>>() {
		}.getType());
	}
	/**
	 * 转成ArrayList
	 * 解决泛型问题
	 */
	public static <T> ArrayList<T> jsonToArrayList(String json, Class<T> cls) {
		ArrayList<T> list = new ArrayList<T>();
		JsonArray array = new JsonParser().parse(json).getAsJsonArray();
		for (final JsonElement elem : array) {
			list.add(mGson.fromJson(elem, cls));
		}
		return list;
	}
	
	
	/**
	 * 格式化json字符串
	 */
	public static String formatJson(String jsonStr) {
		if (null == jsonStr || "".equals(jsonStr)) {
			return "";
		}
		StringBuffer sb = new StringBuffer();
		char last = '\0';
		char current = '\0';
		int indent = 0;
		for (int i = 0; i < jsonStr.length(); i++) {
			last = current;
			current = jsonStr.charAt(i);
			//遇到{ [换行，且下一行缩进
			switch (current) {
				case '{':
				case '[':
					sb.append(current);
					sb.append('\n');
					indent++;
					addIndentBlank(sb, indent);
					break;
				//遇到} ]换行，当前行缩进
				case '}':
				case ']':
					sb.append('\n');
					indent--;
					addIndentBlank(sb, indent);
					sb.append(current);
					break;
				//遇到,换行
				case ',':
					sb.append(current);
					if (last != '\\') {
						sb.append('\n');
						addIndentBlank(sb, indent);
					}
					break;
				default:
					sb.append(current);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 添加space
	 */
	private static void addIndentBlank(StringBuffer sb, int indent) {
		for (int i = 0; i < indent; i++) {
			sb.append('\t');
		}
	}
	
	/**
	 * http 请求数据返回 json 中中文字符为 unicode 编码转汉字转码
	 */
	public static String decodeUnicode(String theString) {
		char aChar;
		int len = theString.length();
		StringBuffer outBuffer = new StringBuffer(len);
		for (int x = 0; x < len; ) {
			aChar = theString.charAt(x++);
			if (aChar == '\\') {
				aChar = theString.charAt(x++);
				if (aChar == 'u') {
					int value = 0;
					for (int i = 0; i < 4; i++) {
						aChar = theString.charAt(x++);
						switch (aChar) {
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								value = (value << 4) + aChar - '0';
								break;
							case 'a':
							case 'b':
							case 'c':
							case 'd':
							case 'e':
							case 'f':
								value = (value << 4) + 10 + aChar - 'a';
								break;
							case 'A':
							case 'B':
							case 'C':
							case 'D':
							case 'E':
							case 'F':
								value = (value << 4) + 10 + aChar - 'A';
								break;
							default:
								throw new IllegalArgumentException(
										"Malformed   \\uxxxx   encoding.");
						}
						
					}
					outBuffer.append((char) value);
				} else {
					if (aChar == 't') {
						aChar = '\t';
					} else if (aChar == 'r') {
						aChar = '\r';
					} else if (aChar == 'n') {
						aChar = '\n';
					} else if (aChar == 'f') {
						aChar = '\f';
					}
					outBuffer.append(aChar);
				}
			} else {
				outBuffer.append(aChar);
			}
		}
		return outBuffer.toString();
	}
}
